package com.costeaalex.MIDlets.remote;
//import java.io.IOException;
import java.io.IOException;
import java.util.Vector;

import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.microedition.lcdui.Display;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.microedition.rms.RecordStore;

import com.costeaalex.MIDlets.display.DisplayManager;
import com.costeaalex.MIDlets.remote.bluetooth.DeviceFinder;
import com.costeaalex.MIDlets.remote.bluetooth.ServiceFinder;
import com.costeaalex.MIDlets.remote.canvas.MouseCanvas;
import com.costeaalex.MIDlets.remote.communication.BluetoothConnection;
import com.costeaalex.MIDlets.remote.communication.CommunicationManager;
import com.costeaalex.MIDlets.remote.lists.DeviceList;
import com.costeaalex.MIDlets.remote.lists.InterfacesList;
import com.costeaalex.MIDlets.remote.lists.ServiceList;
//import com.costeaalex.MIDlets.remote.screens.ScreenConnected;
import com.costeaalex.MIDlets.remote.screens.ScreenConnecting;
import com.costeaalex.MIDlets.remote.screens.ScreenDebug;
import com.costeaalex.MIDlets.remote.screens.ScreenSearchingDevices;
import com.costeaalex.MIDlets.remote.screens.ScreenSearchingServices;
import com.costeaalex.MIDlets.remote.screens.ScreenSetupComplete;
import com.costeaalex.MIDlets.remote.screens.ScreenStartupSettings;
import com.costeaalex.MIDlets.remote.threads.Receiver;
import com.costeaalex.MIDlets.remote.threads.Sender;

public class BlueMIDlet extends MIDlet
	{

	private Display displayMIDlet;
	private DeviceList devices; 
	private ServiceList services;
	private DeviceFinder deviceFind;
	private ServiceFinder serviceFind;
	private ScreenSearchingDevices searchingDev;
	private ScreenSearchingServices searchingServ;
	private ScreenConnecting screenConnecting;
	private ScreenDebug screenDebug;
	private CommunicationManager commManager;
	//private ScreenConnected screenConnected;
	private ScreenStartupSettings screenStartup;
	private RecordStore rs;
	private Sender s;
	private Receiver r;
	private InterfacesList interfacesList;
	private Vector interfaces;
	
	private MouseCanvas mC;
	
	private boolean automated=false;
	
	//private TestCanvas tC;
	
	public DisplayManager displayManager;
		
	public BlueMIDlet()
		{
		screenDebug= new ScreenDebug("Debugger", this);
		screenDebug.isShown();//just so that I do not see the annoying warning label
		}
	
	public void setupMIDlet()
		{
		deviceFind = new DeviceFinder(this);
		searchingDev=new ScreenSearchingDevices("Searching for devices",this); 		
		searchingServ=new ScreenSearchingServices("Searching for services",this);	
		screenConnecting=new ScreenConnecting("Attemping to connect", this);
		displayManager=new DisplayManager(searchingDev, displayMIDlet);
		deviceFind.findDevices();
		//screenConnected=new ScreenConnected("Connected",this);
		}

	protected void destroyApp(boolean arg0) throws MIDletStateChangeException
		{
		// TODO Auto-generated method stub
		}

	protected void pauseApp()
		{
		// TODO Auto-generated method stub
		}

	protected void startApp() throws MIDletStateChangeException
		{
		displayMIDlet = Display.getDisplay(this);
		//displayMIDlet.setCurrent(tC);
		
		if(RecordStore.listRecordStores()==null)
			{
			try
				{
				rs=RecordStore.openRecordStore("SETTINGS", true);
				}
			catch (Exception e)
				{
				e.printStackTrace();
				}
			setupMIDlet();
			}
		else
			{
			try
				{
				rs=RecordStore.openRecordStore("SETTINGS", true);
				screenStartup=new ScreenStartupSettings(rs, this);
				screenStartup.start();
				displayManager=new DisplayManager(screenStartup.form, displayMIDlet);
				}
			catch (Exception e)
				{
				e.printStackTrace();
				}
			}
		}
	
	public void devicesFound(Vector devicesFound)
		{
		int i;
		String rDAddress=null;
		
		if(!automated)
			{
			devices=new DeviceList(devicesFound, this);
			displayManager.advanceToChild(devices.deviceList);
			}
		else
			{
			try
				{
				rDAddress=new String(rs.getRecord(1));
				for(i=0; i<devicesFound.size(); i++)
					{
					if(((RemoteDevice) devicesFound.elementAt(i)).getBluetoothAddress().equals(rDAddress))
						{
						serviceFind=new ServiceFinder(this);
						serviceFind.findServices(((RemoteDevice) devicesFound.elementAt(i)));
						}
					}
				}
			catch (Exception e)
				{
				e.printStackTrace();
				}
			}
		}
	
	public void deviceSelected(RemoteDevice rD)
		{
		
		//screenDebug.setDebugTest(rD.getBluetoothAddress());
		//displayManager.advanceToChild(screenDebug);
			
		serviceFind=new ServiceFinder(this);
		displayManager.advanceToChild(searchingServ);
		try
			{
			rs.addRecord(rD.getBluetoothAddress().getBytes(), 0, rD.getBluetoothAddress().length());
			}
		catch (Exception e)
			{
			e.printStackTrace();
			}
		serviceFind.findServices(rD);
		}
	
	public void servicesFound(ServiceRecord[] servicesFound)
		{
		
		String rDService=null;
		int i;
		
		if(!automated)
			{
			displayManager.returnToParent();
			services = new ServiceList(servicesFound, this);
			displayManager.advanceToChild(services.serviceList);
			}
		else
			{
			try
				{
				rDService=new String(rs.getRecord(2));
				for(i=0; i<servicesFound.length; i++)
					{
					if(servicesFound[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false).equals(rDService))
						{
						connect(servicesFound[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false));
						break;
						}
					}
				}
			catch (Exception e)
				{
				e.printStackTrace();
				}
			}
		}
	
	public void connect(String connectionURL)
		{
		displayManager.advanceToChild(screenConnecting);
		commManager=new BluetoothConnection(connectionURL);
		//screenConnected=new ScreenConnected(connManager,this);
		displayManager.returnToParent();
		//displayManager.advanceToChild(screenConnected.commands);
		s=new Sender(commManager);
		s.start();
		r=new Receiver(commManager);
		r.start();
		
		if(automated)
			{
			interfaces=new Vector();
			mC=new MouseCanvas(commManager, this);
			interfaces.addElement(mC);
			interfacesList=new InterfacesList(this, interfaces);
			displayManager.advanceToChild(interfacesList.list);
			r.addReceiver(mC);
			}
		else
			{
			try
				{
				rs.addRecord(connectionURL.getBytes(), 0, connectionURL.length());
				ScreenSetupComplete sc=new ScreenSetupComplete(this);
				displayManager.advanceToChild(sc.mainform);
				}
			catch (Exception e)
				{
				e.printStackTrace();
				}
			}
		}
	
	public void shutDown()
		{
		try
			{
			try
				{
				if(s!=null)
					s.destroy();
				
				if(commManager!=null)
					commManager.close();
				this.destroyApp(true);
				notifyDestroyed();
				}
			catch (IOException e)
				{
				e.printStackTrace();
				}
			}
		catch (MIDletStateChangeException e)
			{
			e.printStackTrace();
			}
		}

	public void startUp()
		{
		automated=true;
		deviceFind = new DeviceFinder(this);
		deviceFind.findDevices();	
		}
	
	}
